package com.kk.demo.systemshutdown;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

public class SystemShutdownTest {

	private volatile boolean runFlag = true;

	// 使用map记录到当前正在运行的线程，然后等待退出
	private Map<Long, Boolean> blackMap = new ConcurrentHashMap<>();

	public static void main(String[] args) {

		SystemShutdownTest system = new SystemShutdownTest();

		RunThread runThr = system.new RunThread();
		// 进行系统的停机测试
		Thread threadRun = new Thread(runThr);
		threadRun.start();
		// 实例化测试
		Runtime.getRuntime().addShutdownHook(new Thread(system.checkShutdown()));

	}

	/**
	 * 进行运行的线程 data : 2017年4月24日 version : 0.0.1
	 * 
	 * @author liujun
	 */
	@SuppressWarnings("static-access")
	public Runnable checkShutdown() {
		return () -> {
			System.out.println("curr recive stop !!");
			// 将线程改为停机
			runFlag = false;

			while (true) {

				boolean isOver = true;

				// 不断检测一次执行状态，如果线程一直没有执行完毕，超时后，放弃等待
				Iterator<Entry<Long, Boolean>> iter = blackMap.entrySet().iterator();

				Entry<Long, Boolean> entry = null;

				while (iter.hasNext()) {
					entry = iter.next();
					if (!entry.getValue()) {
						isOver = false;
					}
				}

				if (isOver) {
					break;
				} else {
					try {
						System.out.println("curr shutdown sleep 2000 secound");
						Thread.currentThread().sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}

		};
	}

	/**
	 * 进行运行的线程 data : 2017年4月24日 version : 0.0.1
	 * 
	 * @author liujun
	 */
	class RunThread implements Runnable {

		@Override
		public void run() {
			System.out.println("curr is runThread sleep 20000 millis");
			blackMap.put(Thread.currentThread().getId(), false);
			while (runFlag) {
				try {
					Thread.sleep(1000);
					System.out.println("curr thread " + Thread.currentThread().getId() + " is runing!");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}

			System.out.println("RunThread is over!");
			blackMap.put(Thread.currentThread().getId(), true);
		}

	}

}
